home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / TestParts / Draw / DrawObj.cpp < prev    next >
Encoding:
Text File  |  1997-01-01  |  54.9 KB  |  1,864 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DrawObj.cpp
  3.  
  4.     Contains:    Object accessor implementation for the AppleTestDraw_DrawPart
  5.  
  6.     Owned by:    Caia Grisar
  7.  
  8.     Copyright:    © 1993 - 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <5>      1/3/97    JP        1607652 OpenDoc OSL leaks resolved direct
  13.                                     object/subject attribute
  14.          <4>      12/13/96    JP        1611571: Renamed parameter
  15.          <3>     9/23/96    JP        1384958: Added test code for
  16.                                     ShouldHandleEvent
  17.          <2>    .03.1996    NP        1333523: Fixed memory leak in
  18.                                     HandleGetData.
  19.         <43>    10/10/95    NP        1290945: Memory leaks.
  20.         <42>    25/09/95    NP        1979071: Check results of operator new.
  21.         <41>     9/11/95    JP        1269048 & 1283405: Use ODGetComments
  22.         <40>      9/6/95    eeh        1282767: cleanup
  23.         <39>      9/4/95    TJ        Added Includes to Compile with out
  24.                                     PC-Headers.
  25.         <38>     8/25/95    JP        1262410: Comments part to frame fallout
  26.         <37>     7/27/95    eeh        1204615: handle 'exmn' as container
  27.         <36>     6/30/95    JP        Accessor foo
  28.         <35>     6/28/95    eeh        1262143: dispose AEDescs
  29.         <34>     6/26/95    JBS        &DMc&TÇ 1242642 BB: Refcounting Fixes.
  30.         <33>     6/20/95    NP        1260389: Fix DrawPart's count proc,
  31.                                     1260922:  Fix DrawPart's compare proc
  32.         <32>     6/19/95    eeh        ????? return errAEEventNotHandled to
  33.                                     trigger defaults
  34.         <31>     6/13/95    eeh        1250399, 1254943, 1251194: handlers/
  35.                                     accessors return right codes
  36.         <30>      6/7/95    BM        #1252253:  ContainerPart doesn't always
  37.                                     give default event handlers a chance.
  38.                                     Changed HandleGetData, HandleSetData to
  39.                                     return proper error (instead of an
  40.                                     ASSERTM).
  41.         <29>     5/26/95    RR        #1251403: Multithreading naming support
  42.         <28>     5/21/95    NP        1248898: GetUserToken, ODDescToAEDesc, etc.
  43.                                     recipe change.
  44.         <27>     5/18/95    eeh        1250424: added revert event support (dummy)
  45.         <26>      5/3/95    NP        1211084: Remove 5$
  46.         <25>     4/26/95    BM        #1243574: added element accessors
  47.                                     (character from null) and related support
  48.         <24>      4/7/95    eeh        1236842: update on DrawCount
  49.         <23>     3/24/95    eeh        1232264: use ODFrame* rather than ODPart*
  50.                                     to keep track of parts
  51.         <21>     3/21/95    JP        1192027: Include ODRgstry
  52.         <20>     3/20/95    NP        1225985: Change API of CreateSwapToken.
  53.         <19>     3/13/95    NP        1226003: Remove GetContainingFrame from the
  54.                                     API. Use GetContextFromToken.
  55.         <18>      3/2/95    eeh        1214783: finish work on lists
  56.         <17>     2/22/95    eeh        1222901: use StandardPartToken
  57.         <16>     2/21/95    eeh        1214783: remove pName case; add WASSERTS
  58.         <15>     2/13/95    eeh        1217393: enable GetPropertyFromPart
  59.         <14>      2/3/95    eeh        1217393: use new ODDesc etc
  60.         <13>     1/27/95    NP        1213948: Fix handlers and accessors.
  61.         <12>     1/25/95    jpa        Renamed SOM class to Container [1213318]
  62.         <11>     1/22/95    NP        GetUserToken et al signature changed
  63.                                     because of change to AE types.
  64.         <10>     1/16/95    eeh        1211798: use new method of dealing with
  65.                                     tokens (GetUserToken etc.)
  66.          <9>    11/15/94    NP        1199847-fixed some object accessors and
  67.                                     event handlers.
  68.          <8>     10/6/94    JBS        1188214: use refcounted Shape & Transform
  69.          <7>     9/29/94    RA        1189812: Mods for 68K build.
  70.          <6>     9/23/94    NP        1185420. Fixed a few problems, some of
  71.                                     which I had probably introduced before.
  72.          <5>     9/22/94    JBS        1188214: coordinate bias implementation
  73.          <4>     9/15/94    NP        1186778: Changed token handling code.
  74.          <3>      9/9/94    NP        1185851: implement scripting.
  75.          <2>      9/8/94    NP        Backed off of a change until SE is working.
  76.          <1>     8/30/94    NP        first checked in
  77.         <11>     5/27/94    jpa        Support new exceptions [1165267]
  78.         <10>      4/6/94    JBS        1155477
  79.          <9>     3/28/94    CG        1153547: include ODSessM.h instead of
  80.                                     ODSessn.h.
  81.          <8>     3/26/94    NP        1153509. Messaging not PowerPC ready.
  82.          <7>     3/26/94    NP        1153053.
  83.          <6>     3/25/94    JA        JPA: GetPlatformTransform -> GetQDOffset
  84.                                     (1153438). JBS: Changed API of
  85.                                     CreateEmbeddedFrameIterator, CanvasChanged
  86.                                     (1153056, 1153059).
  87.          <5>     3/25/94    MB        Symantec ASLM fixes. #1150864
  88.          <4>     3/25/94    eeh        bug #1153053: Changes for PPC nativity
  89.          <3>     3/15/94    MB        Changes to support SCpp/ASLM builds,
  90.                                     #1150864.
  91.          <2>     2/16/94    JA        Include new AltPoint.h.
  92.         <21>      2/8/94    JA        Added missing #includes.
  93.         <20>      2/8/94    TÇ        Throw -> THROW & some code clean up
  94.         <19>      2/7/94    JA        Utility.h --> ODUtils.h
  95.         <18>      2/7/94    TÇ        fixes to compile with PPC Headers
  96.         <17>      2/2/94    JBS        new AddDisplayFrame recipie
  97.         <16>     1/31/94    NP        Fixed coercion handler to conform to new
  98.                                     interface.
  99.         <15>     1/28/94    NP        Fixed include statements.
  100.         <14>     1/17/94    NP        Removed consts from public API.
  101.         <13>     1/17/94    NP        Semantic Events callbacks API changes.
  102.         <12>     1/14/94    NP        Removed CreateObjSpecifier (it's already in
  103.                                     OpenDoc) and fixed some include statements.
  104.         <11>     1/11/94    eeh        removed "frame" from objspec vocab; work on
  105.                                     Move event and bounds property (not done)
  106.         <10>    12/20/93    NP        Changed calls to CreateSwapToken.
  107.          <9>    12/17/93    eeh        object accessors for frames
  108.          <8>    12/15/93    NP        CreatePartToken -> CreateSwapToken.
  109.          <7>     12/9/93    SS        Compiler conditional #include
  110.          <6>     12/9/93    eeh        implement CreateNewPart,
  111.                                     CreatePartObjectSpec, and SetNewBounds,
  112.                                     helpers, and general support for scripting,
  113.                                     esp the make event
  114.          <5>     12/3/93    TÇ        Stop including ODError.h, it is included
  115.                                     as ErrorDef.h inside Except.h
  116.          <4>     12/1/93    CG        bug fix.
  117.          <3>     12/1/93    CG        Added CreateNewPart, CreatePartObjectSpec,
  118.                                     GetPropertyFromPart,GetPartFromPart,
  119.                                     updated HandleGetData and HandleSetData.
  120.          <2>    11/30/93    JA        Rearranged #includes for new "frame"
  121.                                     constant fix.
  122.          <1>    11/16/93    CG        first checked in
  123.     To Do:
  124. */
  125.  
  126. #ifndef _ALTPOINT_
  127. #include "AltPoint.h"            /* Use C++ savvy ODPoint and ODRect */
  128. #endif
  129.  
  130. #ifndef _ODDESUTL_
  131. #include <ODDesUtl.h>
  132. #endif
  133.  
  134. #ifndef SOM_ODOSLToken_xh
  135. #include <ODOSLTkn.xh>
  136. #endif
  137.  
  138. #ifndef SOM_ODAppleEvent_xh
  139. #include <ODAplEvt.xh>
  140. #endif
  141.  
  142. #ifndef _ORDCOLL_
  143. #include "OrdColl.h"
  144. #endif
  145.  
  146. #ifndef _DRAWOBJ_
  147. #include "DrawObj.h"
  148. #endif
  149.  
  150. #ifndef _DRWSHARED_
  151. #include "DrwShared.h"
  152. #endif
  153.  
  154. #ifndef _PRTPRPAC_
  155. #include "PrtPrpAc.h"
  156. #endif
  157.  
  158. //#ifndef _DFRMITER_
  159. //#include "DFrmIter.h"
  160. //#endif
  161.  
  162. #ifndef SOM_DrawEmbeddedFramesIterator_xh
  163. #include "DrwEmFrI.xh"
  164. #endif
  165.  
  166. #ifndef SOM_ODDraft_xh
  167. #include "Draft.xh"
  168. #endif
  169.  
  170. #ifndef SOM_Module_AppleTestDraw_defined
  171. #include "DrawPart.xh"
  172. #endif
  173.  
  174. #ifndef _EXCEPT_
  175. #include "Except.h"
  176. #endif
  177.  
  178. #ifndef SOM_ODFacet_xh
  179. #include "Facet.xh"
  180. #endif
  181.  
  182. #ifndef SOM_ODFrame_xh
  183. #include "Frame.xh"
  184. #endif
  185.  
  186. #ifndef __LIMITS__
  187. #include <limits.h>
  188. #endif
  189.  
  190. #ifndef SOM_ODNameResolver_xh
  191. #include "NamRslvr.xh"
  192. #endif
  193.  
  194. #ifndef SOM_ODPart_xh
  195. #include "Part.xh"
  196. #endif
  197.  
  198. #ifndef SOM_DrawSI_xh
  199. #include "DrawSI.xh"
  200. #endif
  201.  
  202. #ifndef _ITEXT_
  203. #include "IText.h"
  204. #endif
  205.  
  206. #ifndef _SIHELPER_
  207. #include "SIHelper.h"
  208. #endif
  209.  
  210. #ifndef _ODREGISTRY_
  211. #include "ODRgstry.xh"
  212. #endif
  213.  
  214. #ifndef SOM_ODSession_xh
  215. #include "ODSessn.xh"
  216. #endif
  217.  
  218. #ifndef _SEUTILS_
  219. #include "SEUtils.h"
  220. #endif
  221.  
  222. #ifndef SOM_ODObjectSpec_xh
  223. #include "ODObjSpc.xh"
  224. #endif
  225.  
  226. #ifndef SOM_ODShape_xh
  227. #include "Shape.xh"
  228. #endif
  229.  
  230. #ifndef SOM_ODStorageUnit_xh
  231. #include "StorageU.xh"
  232. #endif
  233.  
  234. #ifndef SOM_ODTransform_xh
  235. #include "Trnsform.xh"
  236. #endif
  237.  
  238. #ifndef SOM_ODMessageInterface_xh
  239. #include "MssgIntf.xh"
  240. #endif
  241.  
  242. #ifndef SOM_ODFrameFacetIterator_xh
  243. #include "FrFaItr.xh"
  244. #endif
  245.  
  246. #ifndef _ODUTILS_
  247. #include "ODUtils.h"
  248. #endif
  249.  
  250. #ifndef __AEOBJECTS__
  251. #include <AEObjects.h>
  252. #endif
  253.  
  254. #ifndef __AEPACKOBJECT__
  255. #include <AEPackObject.h>
  256. #endif
  257.  
  258. #ifndef __AEREGISTRY__
  259. #include <AERegistry.h>
  260. #endif
  261.  
  262. #ifndef __ASREGISTRY__
  263. #include <ASRegistry.h>
  264. #endif
  265.  
  266. #ifndef __TEXTUTILS__
  267. #include <TextUtils.h>
  268. #endif
  269.  
  270. #include <string.h>
  271.  
  272. #ifndef _PRTELMAC_
  273. #include "PrtElmAc.h"
  274. #endif
  275.  
  276. #ifndef _INFOUTIL_
  277. #include <InfoUtil.h>
  278. #endif
  279.  
  280. #ifndef _ODDEBUG_
  281. #include "ODDebug.h"
  282. #endif
  283.  
  284. #ifndef _BARRAY_
  285. #include "BArray.h"
  286. #endif
  287.  
  288. #pragma segment DrawObj
  289.  
  290.  
  291. //==============================================================================
  292. // Function prototypes
  293. //==============================================================================
  294.  
  295. static void CreatePartObjectSpec(DescType keyForm, AEDesc* containerObjSpec,
  296.         AEDesc *objectSpec);
  297. static void MoveFacetTransform(ODFacet* facet, Point* desiredLocation,
  298.         ODPart* part);
  299. void GetDirectParam(ODSession* session, AppleEvent* message,
  300.         AEDesc* evtDp);
  301.  
  302.  
  303. #define CONTAINER_ACCESSOR_RETURN_TYPE        static pascal ODError
  304.  
  305. void InstallStaticCallbacks( ODSemanticInterface* semtIntf,
  306.         SIHelper* helper, ODSession* session )
  307. {
  308.     ODObjectAccessorUPP theAccessorUPP ;
  309.  
  310.     theAccessorUPP = NewODObjectAccessorProc( GetPropertyFromNULL ) ;
  311.     helper->InstallObjectAccessor(cProperty, typeNull, theAccessorUPP,
  312.                                         (ODSLong)session);
  313.  
  314.     theAccessorUPP = NewODObjectAccessorProc( GetPropertyFromNULL ) ;
  315.     helper->InstallObjectAccessor(cProperty, 'exmn', theAccessorUPP,
  316.                                         (ODSLong)session);
  317.  
  318.     theAccessorUPP = NewODObjectAccessorProc( GetPartFromNULL ) ;
  319.     helper->InstallObjectAccessor(cPart, typeNull, theAccessorUPP,
  320.                                         (ODSLong)session);
  321.  
  322.     theAccessorUPP = NewODObjectAccessorProc( GetPartFromNULL ) ;
  323.     helper->InstallObjectAccessor(cPart, 'exmn', theAccessorUPP,
  324.                                         (ODSLong)session);
  325.  
  326.     theAccessorUPP = NewODObjectAccessorProc( GetPropertyFromPart ) ;
  327.      helper->InstallObjectAccessor(cProperty, cPart, theAccessorUPP,
  328.                                         (ODSLong)session);
  329.                                         
  330.     theAccessorUPP = NewODObjectAccessorProc( GetCharFromNULL ) ;
  331.      helper->InstallObjectAccessor(cChar, typeNull, theAccessorUPP,
  332.                                         (ODSLong)session);
  333.  
  334.     theAccessorUPP = NewODObjectAccessorProc( GetCharFromNULL ) ;
  335.      helper->InstallObjectAccessor(cChar, 'exmn', theAccessorUPP,
  336.                                         (ODSLong)session);
  337.  
  338.     theAccessorUPP = NewODObjectAccessorProc( GetWildcardFromPart ) ;
  339.      helper->InstallObjectAccessor(typeWildCard, cPart, theAccessorUPP,
  340.                                         (ODSLong)session);
  341.  
  342.     theAccessorUPP = NewODObjectAccessorProc( GetWildcardFromList ) ;
  343.      helper->InstallObjectAccessor(typeWildCard, typeAEList,
  344.                                         theAccessorUPP, (ODSLong)session);
  345.  
  346.  
  347.     ODEventHandlerUPP theEventHandlerUPP ;
  348.  
  349.     theEventHandlerUPP = NewODEventHandlerProc( HandleSetData ) ;
  350.     helper->InstallEventHandler(kAECoreSuite, kAESetData,
  351.                                                 theEventHandlerUPP,
  352.                                                 (ODSLong)session);
  353.  
  354.     theEventHandlerUPP = NewODEventHandlerProc( HandleGetData ) ;
  355.     helper->InstallEventHandler(kAECoreSuite, kAEGetData,
  356.                                                 theEventHandlerUPP,
  357.                                                 (ODSLong)session);
  358.  
  359.     theEventHandlerUPP = NewODEventHandlerProc( HandleMeow ) ;
  360.     helper->InstallEventHandler('cats', 'meow',
  361.                                                 theEventHandlerUPP,
  362.                                                 (ODSLong)session);
  363.  
  364.     // <eeh> for testing only!!!!
  365.     theEventHandlerUPP = NewODEventHandlerProc( HandleRevert ) ;
  366.     helper->InstallEventHandler('misc', 'rvrt',
  367.                                                 theEventHandlerUPP,
  368.                                                 (ODSLong)session);
  369.  
  370.     theEventHandlerUPP = NewODEventHandlerProc( HandleCreate ) ;
  371.     helper->InstallEventHandler(kAECoreSuite, kAECreateElement,
  372.                                                 theEventHandlerUPP,
  373.                                                 (ODSLong)session);
  374.  
  375.     theEventHandlerUPP = NewODEventHandlerProc( HandleMove ) ;
  376.     helper->InstallEventHandler(kAECoreSuite, kAEMove, theEventHandlerUPP,
  377.                                                 (ODSLong)session);
  378.  
  379.     ODCoercionHandlerUPP coercionHndUPP =
  380.             NewODDescCoercionHandlerProc( CoerceList2RGB ) ;
  381.     helper->InstallCoercionHandler(typeAEList, cRGBColor,
  382.             coercionHndUPP, (ODSLong)kODNULL, kODTrue);
  383.             
  384.     coercionHndUPP =
  385.             NewODDescCoercionHandlerProc( CoerceDPElemToChar ) ;
  386.     helper->InstallCoercionHandler(typeDPElem, typeChar,
  387.             coercionHndUPP, (ODSLong)kODNULL, kODTrue);
  388.  
  389.     ODCompareUPP compUPP = NewODCompareProc( DrawCompare ) ;
  390.     helper->InstallCompareProc(compUPP, (ODSLong)session);
  391.  
  392.     ODCountUPP countUPP = NewODCountProc( DrawCount ) ;
  393.     helper->InstallCountProc(countUPP, (ODSLong)session);
  394.  
  395.     ODDisposeTokenUPP disposeTokenUPP
  396.             = NewODDisposeTokenProc( DrawDisposeToken ) ;
  397.     helper->InstallDisposeTokenProc( disposeTokenUPP, (ODSLong)session);
  398.  
  399. //    Environment* ev = somGetGlobalEnvironment();
  400. //    semtIntf->SetOSLSupportFlags(ev, kAEIDoWhose);
  401. }
  402.  
  403. //------------------------------------------------------------------------------
  404. // GetPropertyFromNULL
  405. //------------------------------------------------------------------------------
  406.  
  407. //#ifdef ODDeleteObject
  408. //#undef ODDeleteObject
  409. //#endif
  410. //#define ODDeleteObject(x)
  411.  
  412.             AEDesc tokenDesc;
  413. //$$$$$
  414.  
  415. CONTAINER_ACCESSOR_RETURN_TYPE GetPropertyFromNULL(ODOBJECT_ACCESSOR_PARAMS)
  416. {
  417. ODUnused(desiredClass);
  418. ODUnused(container);
  419. ODUnused(containerClass);
  420.  
  421.     Environment*            ev = somGetGlobalEnvironment();
  422.     ODSession*                session = (ODSession*)refCon;
  423.     ODNameResolver*        resolver = session->GetNameResolver(ev);
  424.     DescType                propID;
  425.     DrawPartPropAccessor*    accessorObj;
  426.     ODError    error = noErr;
  427.  
  428.     TRY
  429.  
  430.     if (form != formPropertyID)
  431.         THROW(errAEWrongDataType);
  432.  
  433.     AEDesc realData;
  434.     THROW_IF_ERROR( ODDescToAEDesc( selectionData, &realData ) );
  435.     
  436.     propID = **(DescType**)(realData.dataHandle);
  437.     (void)AEDisposeDesc( &realData );
  438.  
  439.     switch( propID )
  440.     {
  441. //        case pBounds:
  442.         case pColor:
  443. //        case pName:            // <eeh> removed because of conflict with user name
  444.             if ( !resolver->IsODToken( ev, value ) )
  445.                 THROW( errAENoSuchObject );
  446.             tokenDesc.descriptorType = cProperty;
  447.             tokenDesc.dataHandle = NewHandle(sizeof(accessorObj));
  448.             THROW_IF_ERROR(MemError());
  449.  
  450.             ODPart* contextPart;
  451.             ODFrame* contextFrame;
  452.             resolver->GetContextFromToken( ev, container, &contextPart,
  453.                     &contextFrame);
  454.  
  455.             accessorObj = new DrawPartPropAccessor(propID, contextFrame);
  456.             SETFIRSTBYTESOFHANDLE(tokenDesc.dataHandle, DrawPartPropAccessor*,
  457.                     accessorObj);
  458. //            ODDesc* usrTokenWrapper = new ODDesc();
  459. //            usrTokenWrapper->InitODDesc(ev);
  460. //            THROW_IF_ERROR( AEDescToODDesc( &tokenDesc, usrTokenWrapper ) );
  461. //            resolver->SetUserToken(ev, value, usrTokenWrapper);
  462. //            ODDeleteObject( usrTokenWrapper );
  463.             ODDesc* userODDesc = resolver->GetUserToken(ev, value);
  464.             THROW_IF_ERROR( AEDescToODDesc( &tokenDesc, userODDesc ) );
  465.             AEDisposeDesc(&tokenDesc);
  466.             break;
  467.         default:
  468. //            THROW(errAECantSupplyType);
  469.             THROW(errAEEventNotHandled);        // let the default try
  470.             break;
  471.     }
  472.     
  473.     CATCH_ALL
  474.         error = ErrorCode();
  475.     ENDTRY
  476.     
  477.     return error;
  478. }    // GetPropertyFromNULL()
  479.  
  480.  
  481.  
  482. //------------------------------------------------------------------------------
  483. // GetPartFromNULL
  484. //------------------------------------------------------------------------------
  485.  
  486. CONTAINER_ACCESSOR_RETURN_TYPE GetPartFromNULL(ODOBJECT_ACCESSOR_PARAMS)
  487. {
  488.     ODUnused(desiredClass);
  489.     ODUnused(container);
  490.     ODUnused(containerClass);
  491.     
  492.     ODUnused(part);
  493.     ODUnused(form);
  494.     ODUnused(selectionData);
  495.     ODUnused(value);
  496.     ODUnused(refCon);
  497. #if 0
  498.     Environment*        ev = somGetGlobalEnvironment();
  499.     ODSession*                session = (ODSession*)refCon;
  500.     ODNameResolver*        resolver = session->GetNameResolver(ev);
  501.     ODSLong                partCount;
  502.     ODSLong                theIndex;
  503.     ODBoolean            allFlag;
  504.     ODBoolean            zeroFlag;
  505.     ODError                result;
  506.     ODUShort             i;
  507.     ODFrame*             frame;
  508.     AEDesc                listItem;
  509.     ODError                error = noErr;
  510. #endif
  511.  
  512.     return errAEEventNotHandled;
  513. #if 0
  514.     if ( !resolver->IsODToken( ev, value ) )
  515.         return errAENoSuchObject;
  516.  
  517.     AEDesc realData;
  518.     ODError err = ODDescToAEDesc( selectionData, &realData );
  519.     if ( err )
  520.         return err;
  521.  
  522.     TRY
  523.  
  524.     partCount = (((AppleTest_Container*)part)->GetEmbeddedFrames(ev))->Count();
  525.     
  526.     if (partCount != 0)
  527.     {
  528.         switch (form)
  529.         {
  530.             case formAbsolutePosition:
  531.                     // Are we being asked for and indexed part
  532.                     // or for all parts?
  533.                 result = DecodeOrdinal(realData, (long)partCount, 
  534.                                 (long*)&theIndex, (Boolean*)&allFlag, (Boolean*)&zeroFlag);
  535.                 THROW_IF_ERROR(result);
  536.                 
  537.                 if (allFlag)
  538.                 {
  539.                     //THROW(errAENoSuchObject);        // don't do lists anymore....
  540.                     THROW(errAEEventNotHandled);        // don't do lists anymore....
  541.                     AEDesc listOfTokens;
  542.                     result = AECreateList( kODNULL, 0, kODFalse, &listOfTokens );
  543.                     THROW_IF_ERROR(result);
  544.         
  545.                         // Get theEmbeddedPart number theIndex
  546.                     DrawEmbeddedFramesIterator* iter = 
  547.                             (DrawEmbeddedFramesIterator*)part->CreateEmbeddedFramesIterator(ev, kODNULL);
  548.                     for (frame = iter->First(ev), i=1; iter->IsNotComplete(ev); frame = iter->Next(ev), i++)
  549.                     {    
  550.                         if (frame)
  551.                         {
  552.                             listItem.descriptorType = kODStandardPartTokenType;
  553.                             listItem.dataHandle = NewHandle(sizeof(StandardPartToken));
  554.                             THROW_IF_ERROR(MemError());
  555.  
  556.                             StandardPartToken spt;
  557.                             spt.fPart = frame->AcquirePart(ev);
  558.                             spt.fFrame = frame;
  559.                             
  560.                             SETFIRSTBYTESOFHANDLE(listItem.dataHandle,
  561.                                     StandardPartToken, spt );
  562.                         
  563.                             result = AEPutDesc(&listOfTokens, i, &listItem);
  564.                             THROW_IF_ERROR(result);
  565.                             
  566.                             result = AEDisposeDesc(&listItem);
  567.                             THROW_IF_ERROR(result);
  568.                         }
  569.                     }
  570. //                    ODDesc* wrapperDesc = new ODDesc();
  571. //                    wrapperDesc->InitODDesc(ev);
  572. //                    THROW_IF_ERROR( AEDescToODDesc( &listOfTokens, wrapperDesc ) );
  573. //                    resolver->SetUserToken(ev, value, wrapperDesc);
  574. //                    ODDeleteObject( wrapperDesc );
  575.                     UpdateUserToken(ev, resolver, value, &listOfTokens);
  576.                 }
  577.                 else
  578.                 {
  579.                         // Get theEmbeddedPart number theIndex
  580.                     DrawEmbeddedFramesIterator* iter = 
  581.                             (DrawEmbeddedFramesIterator*)part->
  582.                             CreateEmbeddedFramesIterator(ev, kODNULL);
  583.                     for (frame = iter->First(ev), i=1; iter->IsNotComplete(ev); frame = iter->Next(ev), i++)
  584.                     {    
  585.                         if (i == theIndex)
  586.                         {
  587.                             break;
  588.                         }
  589.                     }
  590.                     
  591.                     if (frame)
  592.                     {
  593.                         AEDesc myToken;
  594.                         myToken.descriptorType = kODStandardPartTokenType;
  595.                         myToken.dataHandle = NewHandle(sizeof(StandardPartToken));
  596.                         THROW_IF_ERROR(MemError());
  597.  
  598.                         StandardPartToken spt;
  599.                         spt.fPart = frame->AcquirePart(ev);
  600.                         spt.fFrame = frame;
  601.                         
  602.                         SETFIRSTBYTESOFHANDLE(myToken.dataHandle,
  603.                                 StandardPartToken, spt );
  604.  
  605. //                        ODDesc* wrapperDesc = new ODDesc();
  606. //                        wrapperDesc->InitODDesc(ev);
  607. //                        THROW_IF_ERROR( AEDescToODDesc( &myToken, wrapperDesc ) );
  608. //                        resolver->SetUserToken(ev, value, wrapperDesc);
  609. //                        ODDeleteObject( wrapperDesc );
  610.                         UpdateUserToken(ev, resolver, value, &myToken);
  611.                     }
  612.                     else
  613.                         //THROW(errAENoSuchObject);
  614.                         THROW(errAEEventNotHandled);
  615.                 }
  616.                 break;
  617.             default:
  618.                 //THROW(errAENoSuchObject);
  619.                 THROW(errAEEventNotHandled);
  620.                 break;
  621.         }
  622.     }
  623.     else
  624.         //THROW(errAENoSuchObject);
  625.         THROW(errAEEventNotHandled);
  626.     
  627.     CATCH_ALL
  628.     error = ErrorCode();
  629.     ENDTRY
  630.     
  631.     (void)AEDisposeDesc( &realData );
  632.     return error;
  633. #endif // 0
  634. }    // GetPartFromNULL()
  635.                                 
  636. //------------------------------------------------------------------------------
  637. // GetPropertyFromPart
  638. //------------------------------------------------------------------------------
  639.  
  640. CONTAINER_ACCESSOR_RETURN_TYPE GetPropertyFromPart(ODOBJECT_ACCESSOR_PARAMS)
  641. {
  642.     ODUnused(desiredClass);
  643.     ODUnused(containerClass);
  644.     
  645.     ODUnused(part);
  646.     ODUnused(form);
  647.     ODUnused(selectionData);
  648.     ODUnused(value);
  649.     ODUnused(refCon);
  650. #if 0
  651.     Environment*    ev = somGetGlobalEnvironment();
  652.     ODSession*            session = (ODSession*)refCon;
  653.     ODNameResolver*    resolver = session->GetNameResolver(ev);
  654.     DescType            propID;
  655.     ODError            error = noErr;
  656.  
  657.     ODDesc* token;
  658.     token = resolver->GetUserToken(ev, container);
  659.     AEDesc tokenDesc;
  660.     error = ODDescToAEDesc( token, &tokenDesc );
  661.     if ( error ) 
  662.         return error;
  663.  
  664.     TRY
  665.  
  666.     if (form != formPropertyID)
  667.         THROW(errAEWrongDataType);
  668.     if( tokenDesc.descriptorType != kODStandardPartTokenType )
  669.         THROW(errAEWrongDataType);
  670.  
  671.     StandardPartToken spt = FIRSTBYTESFROMHANDLE( tokenDesc.dataHandle,
  672.             StandardPartToken );
  673.     if( !spt.fFrame )
  674.         THROW(errAENoSuchObject);
  675.  
  676.     AEDesc realSelData;
  677.     THROW_IF_ERROR( ODDescToAEDesc( selectionData, &realSelData ) );
  678.  
  679.     propID = **(DescType**)(realSelData.dataHandle);
  680.     switch (propID)
  681.     {
  682.          case pTranslation:
  683.         case pBounds:
  684.             if ( !resolver->IsODToken( ev, value ) )
  685.                 THROW( errAENoSuchObject );
  686.             EmbeddedPartPropAccessor* accessorObj;
  687.             AEDesc tokenDesc;
  688.             tokenDesc.descriptorType = typeEmbededPartProp;
  689.             tokenDesc.dataHandle = NewHandle(sizeof(accessorObj));
  690.             THROW_IF_ERROR(MemError());
  691.  
  692.             accessorObj = new EmbeddedPartPropAccessor(propID, spt.fFrame,
  693.                             (AppleTest_Container*)part);
  694.             SETFIRSTBYTESOFHANDLE(tokenDesc.dataHandle,EmbeddedPartPropAccessor*,
  695.                     accessorObj);
  696.  
  697. //            ODDesc* wrapperDesc = new ODDesc();
  698. //            wrapperDesc->InitODDesc(ev);
  699. //            THROW_IF_ERROR( AEDescToODDesc( &tokenDesc, wrapperDesc ) );
  700. //            resolver->SetUserToken(ev, value, wrapperDesc);
  701. //            ODDeleteObject( wrapperDesc );
  702.             UpdateUserToken(ev, resolver, value, &tokenDesc);
  703.             break;
  704.         default:
  705.             resolver->CreateSwapToken(ev, value, spt.fPart, spt.fFrame);
  706.             break;
  707.     }
  708.  
  709.     
  710.     CATCH_ALL
  711.     error = ErrorCode();
  712.     ENDTRY
  713.     
  714.     return error;
  715. #endif
  716.     return errAEEventNotHandled;
  717. }    // GetPropertyFromPart()
  718.  
  719. //------------------------------------------------------------------------------
  720. // GetWildcardFromPart
  721. //------------------------------------------------------------------------------
  722.  
  723. CONTAINER_ACCESSOR_RETURN_TYPE GetWildcardFromPart(ODOBJECT_ACCESSOR_PARAMS)
  724. {
  725.     ODUnused(part);
  726.     ODUnused(desiredClass);
  727.     ODUnused(containerClass);
  728.     ODUnused(form);
  729.     ODUnused(selectionData);
  730. #if 0 //#
  731.     Environment*    ev = somGetGlobalEnvironment();
  732.     ODError            error = noErr;
  733.  
  734.     TRY
  735.  
  736.     // we need to just return a switch here: we can't go into the part.
  737.     ODNameResolver* resolver = ((ODSession*)refCon)->GetNameResolver(ev);
  738.  
  739.     if ( !resolver->IsODToken( ev, value ) )
  740.         THROW( errAENoSuchObject );
  741.     AEDesc containerToken;
  742.     resolver->GetUserToken( ev, container, &containerToken );
  743.  
  744.     // REMEMBER: I don't know what kind of part this is!
  745.     ODFrame* frame = FIRSTBYTESFROMHANDLE(containerToken.dataHandle, ODFrame*);;
  746.  
  747.     resolver->CreateSwapToken(ev, value, frame);
  748.     
  749.     CATCH_ALL
  750.         error = ErrorCode();
  751.     ENDTRY
  752.     
  753.     return error;
  754. #endif // 0 //#
  755.     return errAEEventNotHandled; //#
  756. }    // GetWildcardFromPart()
  757.  
  758.  
  759. //------------------------------------------------------------------------------
  760. // GetWildcardFromList
  761. //------------------------------------------------------------------------------
  762.  
  763. CONTAINER_ACCESSOR_RETURN_TYPE GetWildcardFromList(ODOBJECT_ACCESSOR_PARAMS)
  764. {
  765. ODUnused(containerClass);
  766. #if 0 //#
  767.     ODError    result;
  768.     ODSLong    itemCount;
  769.     AEKeyword    theAEKeyword;
  770.     ODOSLToken    thisItem;
  771.     ODOSLToken    myToken;
  772.     ODSLong    i;
  773.     ODError    error = noErr;
  774.  
  775.     TRY
  776.  
  777.     Environment*    ev = somGetGlobalEnvironment();
  778.     ODSession*                session = (ODSession*)refCon;
  779.     ODNameResolver*        resolver = session->GetNameResolver(ev);
  780.  
  781.     result = AECountItems(container, &itemCount);
  782.     THROW_IF_ERROR(result);
  783.     
  784.     result = AECreateList(nil,0,false,value);
  785.     THROW_IF_ERROR(result);
  786.  
  787.     for (i=1;i<=itemCount;++i)
  788.     {
  789.         result = AEGetNthDesc(container,i,typeWildCard, 
  790.                                             &theAEKeyword, &thisItem);
  791.         THROW_IF_ERROR(result);
  792.  
  793.         resolver->CallObjectAccessor(ev, thisPart, desiredClass, &thisItem, 
  794.                         thisItem.descriptorType, form, selectionData, 
  795.                         &myToken);
  796.  
  797.         result = AEPutDesc(value, 0, &myToken);
  798.         THROW_IF_ERROR(result);
  799.  
  800.         result = AEDisposeDesc(&thisItem);
  801.         THROW_IF_ERROR(result);
  802.  
  803.         result = AEDisposeDesc(&myToken);
  804.         THROW_IF_ERROR(result);
  805.     }
  806.     
  807.     CATCH_ALL
  808.     error = ErrorCode();
  809.     ENDTRY
  810.     
  811.     return error;
  812. #endif // 0 //#
  813.     return errAEEventNotHandled; //#
  814. }    // GetWildcardFromList()
  815.  
  816.  
  817. //------------------------------------------------------------------------------
  818. // HandleSetData
  819. //------------------------------------------------------------------------------
  820.  
  821. CONTAINER_ACCESSOR_RETURN_TYPE HandleSetData(ODEVENT_HANDLER_PARAMS)
  822. {
  823.     ODUnused(part);
  824.     ODUnused(reply);
  825.  
  826.     AEDesc theData;
  827.     ODError    error = noErr;
  828.     
  829.     Environment*    ev = somGetGlobalEnvironment();
  830.     ODNameResolver* resolver =
  831.             ((ODSession*)handlerRefcon)->GetNameResolver(ev);
  832.  
  833.     AppleEvent realMessage, realReply;
  834.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage) );
  835.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply ));
  836.  
  837.     ODOSLToken* tmpWrapper = kODNULL;
  838.     TRY
  839.     
  840.     THROW_IF_ERROR(AEGetKeyDesc(&realMessage, keyAEData,
  841.               typeWildCard, &theData));
  842.  
  843.     AEDesc evtDp;
  844.     GetDirectParam( (ODSession*)handlerRefcon, &realMessage, &evtDp);
  845.     tmpWrapper = new ODOSLToken();
  846.     THROW_IF_NULL(tmpWrapper);
  847.     tmpWrapper->InitODOSLToken(ev);
  848.     THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  849.     if ( !resolver->IsODToken( ev, tmpWrapper ) )
  850.         THROW( errAENoSuchObject );
  851.     ODDesc* myTokenODDesc;
  852.     myTokenODDesc = resolver->GetUserToken(ev, tmpWrapper);
  853.     AEDesc theToken;
  854.     error = ODDescToAEDesc(myTokenODDesc, &theToken );
  855.  
  856.     if (error == noErr)
  857.     {
  858.         switch (theToken.descriptorType)
  859.         {
  860.             case typeEmbededPartProp:
  861.             case typeFrameProp:
  862.             case typeProperty:
  863.                 AbsDrawPartPropAccessor* embedPropAccessorObj =
  864.                         FIRSTBYTESFROMHANDLE(theToken.dataHandle, AbsDrawPartPropAccessor*);
  865.                 embedPropAccessorObj->SetData(&theData);
  866. //                delete embedPropAccessorObj;
  867.                 break;
  868.             case typeDPElem:
  869.                 DrawPartElemAccessor* elemAccessorObj = FIRSTBYTESFROMHANDLE(
  870.                         theToken.dataHandle, DrawPartElemAccessor* );
  871.                 elemAccessorObj->SetData(&theData);
  872. //                delete elemAccessorObj;
  873.                 break;
  874.                 
  875.             default:
  876.                 //ASSERTM(false, errAECantSupplyType, "You shouldn't be here");
  877.                 THROW(errAEEventNotHandled);
  878.         }
  879.     }
  880.     AEDisposeDesc(&theData);
  881.     THROW_IF_ERROR(error);
  882.  
  883.     CATCH_ALL
  884.         error = ErrorCode();
  885.     ENDTRY
  886.     
  887.     ODDeleteObject( tmpWrapper );
  888.     return error;
  889. }    // HandleSetData()
  890.  
  891.  
  892. //------------------------------------------------------------------------------
  893. // HandleGetData
  894. //------------------------------------------------------------------------------
  895.  
  896. CONTAINER_ACCESSOR_RETURN_TYPE HandleGetData(ODEVENT_HANDLER_PARAMS)
  897. {
  898. ODUnused(part);
  899. ODUnused(handlerRefcon);
  900.  
  901.     DescType        reqType;
  902.     Size            theSize;
  903.     AEDesc            objectData;
  904.     ODError            error;
  905.     Environment*    ev = somGetGlobalEnvironment();
  906.     ODNameResolver* resolver =
  907.             ((ODSession*)handlerRefcon)->GetNameResolver(ev);
  908.     AEDesc            token = NULL_DESCRIPTOR_DEFINITION;
  909.  
  910.     AppleEvent realMessage = NULL_DESCRIPTOR_DEFINITION;
  911.     AppleEvent realReply = NULL_DESCRIPTOR_DEFINITION;
  912.  
  913.     THROW_IF_ERROR( ODDescToAEDesc(message, &realMessage));
  914.     THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply));
  915.  
  916.     ODOSLToken* tmpWrapper = kODNULL;
  917.     
  918.     ODVolatile(tmpWrapper);
  919.     ODVolatile(error);
  920.     
  921.     TRY
  922.         AEDesc evtDp;
  923.         GetDirectParam( (ODSession*)handlerRefcon, &realMessage, &evtDp);
  924.         tmpWrapper = new ODOSLToken();
  925.         THROW_IF_NULL(tmpWrapper);
  926.         tmpWrapper->InitODOSLToken(ev);
  927.         THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  928.         AEDisposeDesc(&evtDp);
  929.         if ( !resolver->IsODToken( ev, tmpWrapper ) )
  930.             THROW( errAENoSuchObject );
  931.         ODDesc* myTokenODDesc;
  932.         myTokenODDesc = resolver->GetUserToken(ev, tmpWrapper);
  933.         THROW_IF_ERROR( ODDescToAEDesc(myTokenODDesc, &token ) );
  934.     
  935.                 //    Next, get the requested return type, if it exists.
  936.         error = AEGetParamPtr(&realMessage, keyAERequestedType, typeType,
  937.                         &reqType, (Ptr)&reqType, sizeof(reqType), &theSize);
  938.         AEDisposeDesc( &realMessage );
  939.         if (error == errAEDescNotFound)        // Not an error if return type is not found.
  940.         {
  941.             error = noErr;
  942.             reqType = typeWildCard;
  943.         }
  944.         THROW_IF_ERROR(error);
  945.     
  946.         switch (token.descriptorType)
  947.         {
  948.             case typeEmbededPartProp:
  949.             case typeFrameProp:
  950.             case typeProperty:
  951.                 AbsDrawPartPropAccessor* propAccessorObj = FIRSTBYTESFROMHANDLE(
  952.                         token.dataHandle, AbsDrawPartPropAccessor*);
  953.                 propAccessorObj->GetData(&objectData);
  954. //                delete propAccessorObj;
  955.                 break;
  956.             case typeDPElem:
  957.                 DrawPartElemAccessor* elemAccessorObj = FIRSTBYTESFROMHANDLE(
  958.                         token.dataHandle, DrawPartElemAccessor* );
  959.                 elemAccessorObj->GetData(&objectData);
  960. //                delete elemAccessorObj;
  961.                 break;
  962.                 
  963.             default:
  964.                 //ASSERTM(false, errAECantSupplyType, "You shouldn't be here");
  965.                 THROW(errAEEventNotHandled);
  966.             
  967.         }
  968.         
  969.         AEDisposeDesc(&token);
  970.         
  971.         error = AEPutParamDesc( &realReply, keyAEResult, &objectData );
  972.         AEDisposeDesc( &objectData );
  973.     
  974.         THROW_IF_ERROR(error);
  975.     
  976.         THROW_IF_ERROR( AEDescToODDesc( &realReply, reply ) );
  977.         AEDisposeDesc( &realReply );
  978.     CATCH_ALL
  979.         ODDisposeAppleEvent(&realMessage);
  980.         ODDisposeAppleEvent(&realReply);
  981.         AEDisposeDesc(&token);
  982.         error = ErrorCode();
  983.     ENDTRY
  984.     
  985.     ODDeleteObject( tmpWrapper );
  986.     return error;
  987. }    // HandleGetData()
  988.  
  989. //------------------------------------------------------------------------------
  990. // HandleCreate
  991. //------------------------------------------------------------------------------
  992.  
  993. // This guy translates the name of the user's new part into a class that
  994. // we can actually use.  Or at least I think that's how it will work.
  995.  
  996. static DescType Partstring2Type(AEDesc* thePartType)
  997. {
  998.     DescType result = cDrawPart;        // default (for now)
  999.  
  1000.     if(thePartType->dataHandle != NULL)
  1001.     {
  1002.         HLock(thePartType->dataHandle);
  1003.         short len = (short)GetHandleSize(thePartType->dataHandle);
  1004.         
  1005.         char* drawpart = "drawpart";
  1006.         char* dragpart = "dragpart";
  1007.         char* clockpart = "clockpart";
  1008.         char* testpart = "testpart";
  1009.         if (IUMagString(*thePartType->dataHandle, drawpart, len,
  1010.                 strlen(drawpart)) == 0)
  1011.             result = cDrawPart;
  1012.         else if (IUMagString(*thePartType->dataHandle, dragpart, len,
  1013.                 strlen(dragpart)) == 0)
  1014.             result = cDragPart;
  1015.         else if (IUMagString(*thePartType->dataHandle, clockpart, len,
  1016.                 strlen(clockpart)) == 0)
  1017.             result = cClockPart;
  1018.         else if (IUMagString(*thePartType->dataHandle, testpart, len,
  1019.                 strlen(testpart)) == 0)
  1020.             result = cTestPart;
  1021.             
  1022.         AEDisposeDesc(thePartType);
  1023.     }
  1024.     return result;
  1025.  
  1026. }    // Partstring2Type()
  1027.  
  1028. CONTAINER_ACCESSOR_RETURN_TYPE HandleRevert(ODEVENT_HANDLER_PARAMS)
  1029. {
  1030.     SysBeep(9);
  1031.     SysBeep(9);
  1032.     SysBeep(9);
  1033.     return noErr;
  1034. }
  1035.  
  1036. CONTAINER_ACCESSOR_RETURN_TYPE HandleCreate(ODEVENT_HANDLER_PARAMS)
  1037. {
  1038. ODUnused(part);
  1039. ODUnused(reply);
  1040. ODUnused(handlerRefcon);
  1041. #if 0
  1042.     Environment*    ev = somGetGlobalEnvironment();
  1043.     ODError            result;
  1044.     DescType        theType;
  1045.     DescType        theClass;
  1046.     ODSize            theSize;
  1047.     AEDesc            replyObject;
  1048.     ODPart*         theNewPart;
  1049.     ODError            error = noErr;
  1050.  
  1051.     TRY
  1052.  
  1053.         //    First, get the object class -- a required parameter
  1054.     result = AEGetParamPtr(message, keyAEObjectClass, typeType, &theType, 
  1055.                     (Ptr)&theClass, sizeof(DescType), (Size *)&theSize);
  1056.     THROW_IF_ERROR(result);
  1057.  
  1058.     if(theClass != cPart)
  1059.         THROW(errAENoSuchObject);
  1060.     
  1061.     AEDesc thePartType;
  1062.     ThrowIfNotAbsent(AEGetParamDesc(message, typeType, typeChar,
  1063.                                 &thePartType));
  1064.     DescType partKind = Partstring2Type(&thePartType);
  1065.     
  1066.         //    Next, get the insertion location -- a required parameter
  1067.     AEDesc theLocation;
  1068.     result = AEGetParamDesc(message, keyAEInsertHere, typeInsertionLoc, 
  1069.                     &theLocation);
  1070.     if (result != errAEDescNotFound)
  1071.         THROW_IF_ERROR(result);
  1072.  
  1073.         // Create the new part
  1074.     theNewPart=((AppleTest_Container*)part)->CreateNewPart(ev, partKind, &theLocation);
  1075.     
  1076.         // have the new part create an object specifier for itself
  1077.     AEDesc containerObjSpec;
  1078.     THROW_IF_ERROR(AEGetAttributeDesc(message, 'subj',
  1079.             typeObjectSpecifier, &containerObjSpec));
  1080.     CreatePartObjectSpec(formAbsolutePosition, &containerObjSpec, &replyObject);
  1081.     AEDisposeDesc(&containerObjSpec);
  1082.  
  1083.         // put the object spec in the result field of reply
  1084.     result = AEPutParamDesc(reply, keyAEResult, &replyObject);
  1085.     AEDisposeDesc(&replyObject);
  1086.     THROW_IF_ERROR(result);
  1087.  
  1088.     // <eeh> But I want it to stick around!!!!
  1089.     // delete theNewPart;
  1090.     // ODReleaseObject(theNewPart);
  1091.  
  1092.     CATCH_ALL
  1093.     error = ErrorCode();
  1094.     ENDTRY
  1095.     
  1096.     return error;
  1097. #endif /* 0 */
  1098.     return errAEEventNotHandled;
  1099. }    // HandleCreate()
  1100.  
  1101. //------------------------------------------------------------------------------
  1102. // HandleMove
  1103. //
  1104. // ALL THIS HANDLES right now is moving a part's frame[s], though I've
  1105. // never tested it on any part with more than one frame!
  1106. //------------------------------------------------------------------------------
  1107.  
  1108. static void MoveFacetTransform(ODFacet* facet, Point* desiredLocation,
  1109.         ODPart* part)
  1110. {
  1111. #if 0
  1112. // DMc refcount - comment out lines to make refbal ignore them
  1113. //    Environment*    ev = somGetGlobalEnvironment();
  1114. //    ODTransform* newXForm = ODCopyAndRelease(facet->GetExternalTransform(ev));
  1115. //    Point curOffset = newXForm->GetQDOffset(ev);
  1116. //    Point scratch = *desiredLocation;
  1117. //    scratch.h -= curOffset.h;
  1118. //    scratch.v -= curOffset.v;
  1119. //
  1120. //    ODPoint newDelta = *desiredLocation = scratch;
  1121. //    newXForm->MoveBy(ev, &newDelta);
  1122. //    facet->ChangeGeometry(ev, kODNULL, newXForm);
  1123. //    facet->Invalidate(ev, kODNULL);
  1124. #endif /* 0 */
  1125. }
  1126.  
  1127. CONTAINER_ACCESSOR_RETURN_TYPE HandleMove(ODEVENT_HANDLER_PARAMS)
  1128. {
  1129. #if 0
  1130. // DMc refcount - comment out lines to make refbal ignore them
  1131. //    ODUnused(handlerRefcon);
  1132. //    ODUnused(reply);
  1133. //
  1134. //    Environment*    ev = somGetGlobalEnvironment();
  1135. //    AppleTest_Container*        thisDrawPart = (AppleTest_Container*) part;
  1136. //    
  1137. //    // Size theSize;
  1138. //    // DescType theType;
  1139. //    ODError    error = noErr;
  1140. //
  1141. //    TRY
  1142. //
  1143. //    AEDesc destination;        // where it's to be moved to
  1144. //    OSErr result = AEGetParamDesc(message, keyAEInsertHere, typeWildCard,
  1145. //            &destination);
  1146. //    THROW_IF_ERROR(result);
  1147. //    
  1148. //    ODOSLToken theToken;        // what I'm supposed to move
  1149. //    THROW_IF_ERROR(AEGetParamDesc(message, keyDirectObject, typeWildCard,
  1150. //            &theToken));
  1151. //    if ((&theToken)->descriptorType != cPart)
  1152. //        THROW();
  1153. //
  1154. //    if (destination.descriptorType == typeObjectSpecifier)    // a path
  1155. //    {
  1156. //        ODOSLToken token;
  1157. //    
  1158. //        ODNameResolver* resolver = ((ODSession*)handlerRefcon)->
  1159. //                GetNameResolver(ev);
  1160. //        // start resolution at the shell
  1161. //        resolver->Resolve(&destination, &token, kODAppShell);
  1162. //
  1163. //        // now replace the location with the token, and pass the
  1164. //        // event to that part.  should I dispose of the token after
  1165. //        // putting it in the AppleEvent?
  1166. //        
  1167. //        THROW_IF_ERROR(AEPutParamDesc(message, keyAEInsertHere, 
  1168. //                &token));
  1169. //        ODPart* embedder;
  1170. //        ODFrame* ignoreF;
  1171. //        resolver->GetContextInfo(ev, &ignoreF, &embedder);
  1172. //        ODMessageInterface* msgInterface = ((ODSession*)handlerRefcon)->
  1173. //                GetMessageInterface(ev);
  1174. //        // NO! PRIVATE METHOD. MUST USE SEND.
  1175. //        THROW_IF_ERROR(msgInterface->DispatchToEventHandler(message,
  1176. //                reply, embedder));
  1177. //
  1178. //    }
  1179. //    else if (destination.descriptorType == cPart)
  1180. //    {
  1181. //        // Here the destination is a token belonging to me.  As the
  1182. //        // embedding part (the last to deal with the token before the
  1183. //        // original recipient of the event finished resolving it) I
  1184. //        // own the destination and can get out of the token what I
  1185. //        // need.
  1186. //        
  1187. //        ODFrame* frameToMoveTo = (ODFrame*)
  1188. //                GetSecondFourBytesFromDataHandle(&destination);
  1189. //        ODFrame* frameToMove
  1190. //                = (ODFrame*)GetSecondFourBytesFromDataHandle(&theToken);
  1191. //
  1192. //
  1193. //        // get some info for the embed call
  1194. //        ODShape* frameShape = ODCopyAndRelease(frameToMove->GetFrameShape(ev));
  1195. //
  1196. //        ODTransform* xtrnlXfrm = ODCopyAndRelease(facet->GetExternalTransform(ev));
  1197. //        ODFrameFacetIterator* fi = frameToMove->CreateFacetIterator(ev);
  1198. //        ODFacet* facet = fi->First(ev);
  1199. //
  1200. //
  1201. //        // remove the frame from the old place
  1202. //        frameToMove->GetContainingFrame(ev)->GetPart(ev)->
  1203. //                RemoveEmbeddedFrame(ev, frameToMove);
  1204. //
  1205. //        // embed it in the new
  1206. //
  1207. //        WASSERT(part == frameToMoveTo->GetPart(ev));
  1208. //
  1209. //        ODFrame* newFrame = thisDrawPart->CreateEmbeddedFrame(ev,
  1210. //                                                frameToMoveTo,
  1211. //                                                frameShape,
  1212. //                                                xtrnlXfrm,
  1213. //                                                frameToMove->GetPart(ev),
  1214. //                                                kODNullTypeToken,
  1215. //                                                kODNullTypeToken,
  1216. //                                                0,
  1217. //                                                kODFalse);
  1218. //        ODReleaseObject(ev, frameShape);
  1219. //        ODReleaseObject(ev, xtrnlXfrm);
  1220. //    }
  1221. //    else
  1222. //    {
  1223. //        // get the point
  1224. //        AEDesc dPoint;
  1225. //        result = AECoerceDesc(&destination, typeQDPoint, &dPoint);
  1226. //        THROW_IF_ERROR(result);
  1227. //        Point pt = **(Point**)dPoint.dataHandle;
  1228. //        AEDisposeDesc(&dPoint);
  1229. //
  1230. //        ODFrame* frameToMove
  1231. //                = (ODFrame*)GetSecondFourBytesFromDataHandle(&theToken);
  1232. //        ODFrameFacetIterator* fi = frameToMove->CreateFacetIterator(ev);
  1233. //        ODFacet* facet = fi->First(ev);
  1234. //        MoveFacetTransform(facet, &pt, frameToMove->GetPart(ev));
  1235. //
  1236. //        Proxy* p = thisDrawPart->ProxyForFrame(frameToMove);
  1237. //
  1238. //        // !!! this is a single-facet hack
  1239. //        p->transform->MoveBy(ev, pt);        
  1240. //        thisDrawPart->UpdateProxyRegion(ev, p);
  1241. //        thisDrawPart->CreateProxySelectionBorder(ev, p);
  1242. //
  1243. //        frameToMove->GetContainingFrame(ev)->Invalidate(ev, (ODShape*)kODNULL);
  1244. //    }
  1245. //
  1246. //    AEDisposeDesc(&destination);
  1247. //
  1248. //    CATCH_ALL
  1249. //    error = ErrorCode();
  1250. //    ENDTRY
  1251. //    
  1252. //    return error;
  1253. #endif /* 0 */
  1254.     return errAEEventNotHandled;
  1255. }    // HandleMove()
  1256.  
  1257. //------------------------------------------------------------------------------
  1258. // Coercelist2RGB
  1259. //
  1260. //    From the AppleScript code and tweaked.
  1261. //------------------------------------------------------------------------------
  1262.  
  1263. #define QDRGBsize            3
  1264.  
  1265. CONTAINER_ACCESSOR_RETURN_TYPE CoerceList2RGB(ODPart* part, AEDesc* from, DescType toType,
  1266.                     ODSLong refcon, AEDesc* result)
  1267. {
  1268. ODUnused(part);
  1269. ODUnused(refcon);
  1270.  
  1271.     OSErr err;
  1272.     AEKeyword dummyKeyword;
  1273.     DescType dummyCode;
  1274.     Size itemSize;
  1275.     long theData[QDRGBsize];
  1276.     unsigned short theRealData[QDRGBsize];
  1277.     ODError    error = noErr;
  1278.  
  1279.     TRY
  1280.  
  1281.     // the data goes R, G, B
  1282.     for (int i=0; i<QDRGBsize; i++) {
  1283.         err = AEGetNthPtr(from, i+1, typeLongInteger, &dummyKeyword,
  1284.                           &dummyCode, (Ptr) &theData[i], sizeof(theData[0]),
  1285.                           &itemSize);
  1286.         if ((err != noErr) || (theData[i] < 0) || (theData[i] > USHRT_MAX))
  1287.             THROW(errAECoercionFail);
  1288.         theRealData[i] = (unsigned short)theData[i];
  1289.     }
  1290.     THROW_IF_ERROR(AECreateDesc(toType, (Ptr)&theRealData,
  1291.                                 QDRGBsize * sizeof(short), result));
  1292.     
  1293.     CATCH_ALL
  1294.     error = ErrorCode();
  1295.     ENDTRY
  1296.     
  1297.     return error;
  1298. }
  1299.  
  1300. //------------------------------------------------------------------------------
  1301. // DrawCompare
  1302. // For now, just handle what we need to handle
  1303. //------------------------------------------------------------------------------
  1304. CONTAINER_ACCESSOR_RETURN_TYPE DrawCompare(    ODPart*            thePart,
  1305.                                             DescType        oper,
  1306.                                             ODOSLToken*        obj1,
  1307.                                             ODOSLToken*        obj2,
  1308.                                             ODBoolean*        result,
  1309.                                             ODSLong            refCon)
  1310. {
  1311. ODUnused(thePart);
  1312.  
  1313.     Environment*    ev = somGetGlobalEnvironment();
  1314.     ODError            error = noErr;
  1315.     ODDesc*            tokenWrapper1;
  1316.     ODDesc*            tokenWrapper2;
  1317.     AEDesc            realToken1 = NULL_DESCRIPTOR_DEFINITION;
  1318.     AEDesc            realToken2 = NULL_DESCRIPTOR_DEFINITION;
  1319.     
  1320.     TRY
  1321.         ODNameResolver*    resolver = ((ODSession*)refCon)->GetNameResolver(ev);
  1322.         
  1323.         switch(oper)
  1324.         {
  1325.             case kAEEquals:
  1326.             
  1327.                 if ( resolver->IsODToken( ev, obj1 ) )
  1328.                 {
  1329.                     tokenWrapper1 = resolver->GetUserToken( ev, obj1 );
  1330.                     THROW_IF_ERROR( ODDescToAEDesc( tokenWrapper1, &realToken1 ) );
  1331.                 }
  1332.                 else THROW_IF_ERROR( ODDescToAEDesc( obj1, &realToken1 ) );
  1333.                 
  1334.                 if ( resolver->IsODToken( ev, obj2 ) )
  1335.                 {
  1336.                     tokenWrapper2 = resolver->GetUserToken( ev, obj2 );
  1337.                     THROW_IF_ERROR( ODDescToAEDesc( tokenWrapper2, &realToken2 ) );
  1338.                 }
  1339.                 else THROW_IF_ERROR( ODDescToAEDesc( obj2, &realToken2 ) );
  1340.                 
  1341.                 if ( ( realToken1.descriptorType == typeDPElem )
  1342.                     || ( realToken2.descriptorType == typeDPElem ) )
  1343.                     *result = CompareDPElemsAndChars( &realToken1, &realToken2 );
  1344.                 else
  1345.                     error = errAEEventNotHandled;
  1346.  
  1347.                 AEDisposeDesc(&realToken1);
  1348.                 AEDisposeDesc(&realToken2);
  1349.         
  1350.                 break;
  1351.                 
  1352.             default:
  1353.                 THROW(errAEEventNotHandled);
  1354.         }
  1355.         
  1356.     CATCH_ALL
  1357.         AEDisposeDesc(&realToken1);
  1358.         AEDisposeDesc(&realToken2);
  1359.         error = ErrorCode();
  1360.     ENDTRY
  1361.     
  1362.     return error;
  1363. }    //DrawCompare
  1364.  
  1365. //------------------------------------------------------------------------------
  1366. // DrawCount
  1367. //------------------------------------------------------------------------------
  1368. CONTAINER_ACCESSOR_RETURN_TYPE DrawCount(    ODPart*            thePart,
  1369.                                             DescType        desiredType,
  1370.                                             DescType        containerClass,
  1371.                                             ODOSLToken*        container,
  1372.                                             ODSLong*        result,
  1373.                                             ODSLong            refCon)
  1374. {
  1375.     Environment*    ev = somGetGlobalEnvironment();
  1376.     ODError            error = noErr;
  1377.     ODIText*        iText = kODNULL;
  1378.     
  1379.     TRY
  1380.         ODNameResolver* resolver =
  1381.                 ((ODSession*)refCon)->GetNameResolver(ev);
  1382.  
  1383.         if ( !resolver->IsODToken(ev, container) )
  1384.             THROW(errAEEventNotHandled);
  1385.     
  1386.         if ( (containerClass == typeNull ) && ( desiredType == cChar ) )
  1387.         {
  1388.             ODFrame*    frame;
  1389.             ODPart* ignorePart;
  1390.             resolver->GetContextFromToken( ev, container, &ignorePart, &frame );
  1391.             iText = ODGetComments( ev, frame, kODNULL );
  1392.             if (!iText)
  1393.                 *result = 0;
  1394.             else
  1395.                 *result = GetITextStringLength(iText);
  1396.         }
  1397.         else if (containerClass == cPart)
  1398.         {    
  1399.             //ODDesc* tokenWrapper;
  1400.             //resolver->GetUserToken( ev, container, &tokenWrapper );
  1401.             //AEDesc token;
  1402.             //THROW_IF_ERROR( ODDescToAEDesc( tokenWrapper, &token ) );
  1403.             //WASSERT( token.descriptorType == kODStandardPartTokenType );
  1404.  
  1405.             //StandardPartToken spt = FIRSTBYTESFROMHANDLE(token.dataHandle,
  1406.                 //StandardPartToken);
  1407.             //WARN( "I've got the part but nothing to do with it...." );
  1408.             // resolver->CreateSwapToken(value, part);
  1409.             *result = kODCountProcSwapValue;
  1410.         }
  1411.         else if (containerClass == typeNull && desiredType == cPart)
  1412.             *result = CountEmbeddedParts(ev, thePart);
  1413.         else
  1414.             error = errAEEventNotHandled;
  1415.     CATCH_ALL
  1416.         error = ErrorCode();
  1417.     ENDTRY
  1418.     
  1419.     if ( iText != kODNULL) DisposeIText(iText);
  1420.  
  1421.     return error;
  1422. //# return errAEEventNotHandled;
  1423. }    //DrawCount
  1424.  
  1425. //------------------------------------------------------------------------------
  1426. // DrawDisposeToken
  1427. //------------------------------------------------------------------------------
  1428. CONTAINER_ACCESSOR_RETURN_TYPE DrawDisposeToken(ODPart*            thePart,
  1429.                             ODOSLToken*    unneededToken,
  1430.                             ODSLong        refCon)
  1431. {
  1432.     ODUnused(thePart);
  1433.  
  1434.     ODSession*        session = (ODSession*)refCon;
  1435.     Environment*    ev = somGetGlobalEnvironment();
  1436.     ODNameResolver*    resolver = session->GetNameResolver(ev);
  1437.     ODBoolean        oneOfOurs = kODFalse;
  1438.     ODByteArray        data;
  1439.  
  1440.     ODDescType    temp = unneededToken->GetDescType(ev);
  1441.     if (resolver->IsODToken( ev, unneededToken ))
  1442.     {
  1443.         ODDesc*    userTokenODDesc = resolver->GetUserToken( ev, unneededToken );
  1444.         ODDescType descType = userTokenODDesc->GetDescType(ev);
  1445.     
  1446.  
  1447. /* CAN"T DEAL WITH cProperty YET BECAUSE THE DEFAULT ACCESSORS USE THIS
  1448.     DESCRIPTOR TYPE AS WELL. DRAWPART WILL THINK THAT ONE OF THE DEFAULT
  1449.     ACCESSORS' TOKENS IS ONE OF ITS OWN AND TRY TO DISPOSE IT. */
  1450.  
  1451.  
  1452.         // BE CAREFUL TO MATCH THE CASES HERE WITH THE CASES IN 2ND SWITCH
  1453.         //    STATEMENT
  1454.         switch(descType)
  1455.         {
  1456. //            case cProperty:
  1457.             case typeEmbededPartProp:
  1458.             case typeDPElem:
  1459.                 oneOfOurs = kODTrue;
  1460.                 data = userTokenODDesc->GetRawData(ev);
  1461.                 break;
  1462.         }
  1463.     
  1464.         if (oneOfOurs)
  1465.         {
  1466.             switch(descType)
  1467.             {
  1468. //                case cProperty:
  1469. //                    ODDeleteObject( *((DrawPartPropAccessor**)data._buffer) );
  1470. //                    break;
  1471.                 case typeEmbededPartProp:
  1472.                     ODDeleteObject( *((EmbeddedPartPropAccessor**)data._buffer) );
  1473.                     break;
  1474.                 case typeDPElem:
  1475.                     ODDeleteObject( *((DrawPartElemAccessor**)data._buffer) );
  1476.                     break;
  1477.                 default:
  1478.                     // THE CASES IN THIS SWITCH DO NOT MATCH THE CASES IN THE
  1479.                     //    ABOVE SWITCH
  1480.                     WARN("DrawDisposeToken: Should never have hit here.");
  1481.                 
  1482.             }
  1483.             DisposeByteArrayStruct(data);
  1484.         }
  1485.     }
  1486.  
  1487.     // LET OPENDOC DELETE THE TOKEN ITSELF
  1488.     return errAEEventNotHandled;
  1489. }
  1490.  
  1491. //------------------------------------------------------------------------------
  1492. // Utility functions
  1493. //------------------------------------------------------------------------------
  1494.  
  1495. void GetDirectParam(ODSession* session, AppleEvent* message,
  1496.         AEDesc* evtDp)
  1497. {
  1498.     Environment* ev = somGetGlobalEnvironment();
  1499.     AEDesc localDP;
  1500.     THROW_IF_ERROR(AEGetParamDesc(message, keyDirectObject, typeWildCard,
  1501.             &localDP));
  1502.  
  1503.     ODNameResolver* resolver = session->GetNameResolver(ev);
  1504.  
  1505.     ODOSLToken* tmpWrapper = new ODOSLToken();
  1506.     THROW_IF_NULL(tmpWrapper);
  1507.     tmpWrapper->InitODOSLToken(ev);
  1508.     THROW_IF_ERROR( AEDescToODDesc(&localDP, tmpWrapper ) );
  1509.  
  1510.     ODBoolean isToken = resolver->IsODToken(ev, tmpWrapper);
  1511.     ODDeleteObject( tmpWrapper );
  1512.     if ( isToken )
  1513.     {
  1514.         *evtDp = localDP;
  1515.     }
  1516.     else
  1517.     {
  1518.         WARN("RlShlEv.cpp: GetDirectParam. Found a non-token.  About to throw.");
  1519.         THROW( errAEEventNotHandled );
  1520.     }
  1521. }    // GetDirectParam()
  1522.  
  1523. // #undef ODDeleteObject
  1524.  
  1525. //------------------------------------------------------------------------------
  1526. // CreatePartObjectSpec
  1527. //------------------------------------------------------------------------------
  1528.  
  1529. static void CreatePartObjectSpec(DescType keyForm, AEDesc* containerObjSpec,
  1530.         AEDesc *objectSpec)
  1531. {
  1532.     // We'll really return a spec to the FRAME containing the part.
  1533.     // This cause you can get to the part from the frame, but not the other
  1534.     // way 'round.
  1535.     
  1536.     AEDesc keyData;
  1537.     
  1538.     switch(keyForm)
  1539.     {
  1540.         case formAbsolutePosition :
  1541.             long index = 1;            // <eeh> we should figure out where
  1542.             THROW_IF_ERROR(AECreateDesc(typeLongInteger, &index, sizeof(index),
  1543.                     &keyData));
  1544.             break;
  1545.         default :
  1546.             ASSERTM(false, -1, "Can't handle that form!!! (yet)");
  1547.     }
  1548.  
  1549.     CreateObjSpecifier(cPart, containerObjSpec, keyForm, &keyData, true,
  1550.             objectSpec);
  1551. }    // CreatePartObjectSpec()
  1552.  
  1553. CONTAINER_ACCESSOR_RETURN_TYPE GetCharFromNULL(ODOBJECT_ACCESSOR_PARAMS)
  1554. {
  1555.     Environment*            ev = somGetGlobalEnvironment();
  1556.     ODSession*                session = (ODSession*)refCon;
  1557.     ODNameResolver*            resolver = session->GetNameResolver(ev);
  1558.     AEDesc                    tokenDesc;
  1559.     AEDesc                    realData;
  1560.     ODPart*                    contextPart;
  1561.     ODFrame*                contextFrame;
  1562.     DrawPartElemAccessor*    accessorObj = kODNULL;
  1563.     ODDesc*                    usrTokenWrapper = kODNULL;
  1564.     ODError                    error = noErr;
  1565.     
  1566.     TRY
  1567.     
  1568.         WASSERT( desiredClass == cChar );
  1569.         
  1570.         THROW_IF_ERROR( ODDescToAEDesc( selectionData, &realData ) );
  1571.         
  1572.         if ( !resolver->IsODToken( ev, value ) ) THROW( errAENoSuchObject );
  1573.         
  1574.         tokenDesc.descriptorType = typeDPElem;
  1575.         tokenDesc.dataHandle = NewHandle(sizeof(accessorObj));
  1576.         THROW_IF_ERROR( MemError() );
  1577.         
  1578.         resolver->GetContextFromToken( ev, container, &contextPart, &contextFrame );
  1579.         
  1580.         accessorObj = new DrawPartElemAccessor();
  1581.         accessorObj->InitElemAccessor( desiredClass, form, &realData, contextFrame );
  1582.         AEDisposeDesc(&realData);
  1583.         SETFIRSTBYTESOFHANDLE( tokenDesc.dataHandle, DrawPartElemAccessor*, accessorObj );
  1584.         
  1585. //        usrTokenWrapper = new ODDesc();
  1586. //        usrTokenWrapper->InitODDesc(ev);
  1587. //        THROW_IF_ERROR( AEDescToODDesc( &tokenDesc, usrTokenWrapper ) );
  1588. //        resolver->SetUserToken( ev, value, usrTokenWrapper );
  1589.         UpdateUserToken(ev, resolver, value, &tokenDesc);
  1590.         
  1591.     CATCH_ALL
  1592.         error = ErrorCode();
  1593.         
  1594.         // I *THINK* the following is right - probably we need a DisposeProc
  1595.         // to handle the internal accessorObj - BHM - NP: This code is fine.
  1596.         //    Your dispose proc will get called eventually by OpenDoc, and in
  1597.         //    there, you should dispose of any auxiliary structures.
  1598.         if DESC_IS_NOT_NULL(tokenDesc)
  1599.         {
  1600.             AEDisposeDesc(&tokenDesc);    // should be AEDisposeToken - BHM
  1601.                                         //    NP: No it shouldn't.
  1602.             MAKE_DESC_NULL(tokenDesc);
  1603.         }
  1604.     ENDTRY
  1605.     
  1606.     if (usrTokenWrapper != kODNULL) ODDeleteObject(usrTokenWrapper);
  1607.     
  1608.     return error;
  1609. }    //    GetCharFromNULL
  1610.  
  1611. //------------------------------------------------------------------------------
  1612. // CompareDPElemsAndChars
  1613. //------------------------------------------------------------------------------
  1614. ODBoolean CompareDPElemsAndChars( AEDesc* aDesc, AEDesc* bDesc )
  1615. {
  1616.  
  1617.     DrawPartElemAccessor*    elemAccessorObj;
  1618.     
  1619.     char    char1;
  1620.     char    char2;
  1621.     
  1622.     if ( aDesc->descriptorType == typeDPElem ) 
  1623.     {
  1624.         elemAccessorObj = FIRSTBYTESFROMHANDLE(
  1625.             aDesc->dataHandle, DrawPartElemAccessor* );
  1626.         char1 = elemAccessorObj->GetOneChar();
  1627.     }
  1628.     else char1 = GetOneCharFromDesc(aDesc);
  1629.         
  1630.     if ( bDesc->descriptorType == typeDPElem )
  1631.     {
  1632.         elemAccessorObj = FIRSTBYTESFROMHANDLE(
  1633.             bDesc->dataHandle, DrawPartElemAccessor* );
  1634.         char2 = elemAccessorObj->GetOneChar();
  1635.     }
  1636.     else char2 = GetOneCharFromDesc(bDesc);
  1637.     
  1638.     return ( char1 == char2 );
  1639. }    //CompareDPElemsAndChars
  1640.  
  1641. //------------------------------------------------------------------------------
  1642. // CoerceDPElemToChar
  1643. //------------------------------------------------------------------------------
  1644. CONTAINER_ACCESSOR_RETURN_TYPE CoerceDPElemToChar(ODPart* part, AEDesc* from, DescType toType,
  1645.                     ODSLong refcon, AEDesc* result)
  1646. {
  1647.     DrawPartElemAccessor* fromAccessorObj;
  1648.     ODError    error = noErr;
  1649.     
  1650.     MAKE_DESC_NULL(*result);
  1651.  
  1652.     TRY
  1653.         WASSERT( from->descriptorType == typeDPElem );
  1654.         WASSERT( toType == typeChar );
  1655.         
  1656.         fromAccessorObj = FIRSTBYTESFROMHANDLE(
  1657.                 from->dataHandle, DrawPartElemAccessor* );
  1658.                 
  1659.         fromAccessorObj->GetData(result);
  1660.         
  1661.     CATCH_ALL
  1662.         error = ErrorCode();
  1663.     ENDTRY
  1664.     
  1665.     return error;
  1666. }    //CoerceDPElemToChar
  1667.  
  1668.  
  1669. #undef ODOBJECT_ACCESSOR_PARAMS
  1670.  
  1671.  
  1672. //------------------------------------------------------------------------------
  1673. //    HandleMeow
  1674. //
  1675. //    This event is here to test and demonstrate the recipe for accepting an
  1676. //    event using either the direct parameter or the subject attribute.  It makes
  1677. //    use of two routines in SEPriv which are copied into this file, 
  1678. //    PartFrameFromStandardPartToken and CanBeStandardPartToken.  This should
  1679. //    enable any container part to determine if an event is targeted at it or 
  1680. //    not.
  1681. //------------------------------------------------------------------------------
  1682. static pascal ODError HandleMeow(    ODPart*            part,
  1683.                                     ODAppleEvent*    message,
  1684.                                     ODAppleEvent*    reply,
  1685.                                     ODSLong            handlerRefcon)
  1686. {
  1687.     ODError                error = noErr;
  1688.     ODOSLToken*            oslToken;
  1689.     ODDesc*                userToken = kODNULL;
  1690.     ODPart*                contextPart = kODNULL;
  1691.     ODPart*                realPart = kODNULL;
  1692.     ODFrame*            contextFrame;
  1693.     AEDesc                realEvent = {typeNull, kODNULL};
  1694.     AEDesc                obj = {typeNull, kODNULL};
  1695.     Environment*        ev = somGetGlobalEnvironment();
  1696.     ODSession*            session = (ODSession*) handlerRefcon;
  1697.     ODNameResolver*        resolver = session->GetNameResolver(ev);
  1698.     ODBoolean            samePart = kODFalse;
  1699.     ODBoolean            disposeToken = kODFalse;
  1700.     ODBoolean            utilSaysHandle;
  1701.     
  1702.     /*
  1703.         This recipe shows how to work around the fact that events without a 
  1704.         direct parameter are sent first to the shell (which you'll never notice),
  1705.         then to the root part (which you will notice if your part is also the root)
  1706.         and then finally to the destination part specified in the subject attribute.
  1707.         In addition, it shows how you can determine the destination frame.
  1708.         
  1709.         Normally, events are sent to the part containing the direct object.
  1710.         This is typically the context of the token which OpenDoc replaces the
  1711.         actual object specifier with.  So normally, you don't even need to look
  1712.         at the direct parameter since you are the object which is handling the 
  1713.         event.  However, in the case where the direct parameter is missing, or
  1714.         where the direct parameter is a part reference (i.e. part "Bob",
  1715.         part id 65535 or part 1 of part 1 of part 1), the dispatching is a bit
  1716.         messy due to the fact that you typically want to send the event to the
  1717.         container of the object (i.e. the part who contains the thing) so when
  1718.         you refer to a part, the container of that part gets the message. Of
  1719.         course, there are some caveats as for who "contains" whom.  Most notably,
  1720.         a "part id 65535" reference is always "contained" by the root part since
  1721.         OpenDoc doesn't walk the tree looking for the actual container.  That's
  1722.         one of the reasons for this recipe.  In addition, it turns out that 
  1723.         the subject attribute is almost always a part reference, so this 
  1724.         case turns out to almost always be true when the direct parameter is
  1725.         missing or is not an object which OpenDoc can resolve.
  1726.         
  1727.         Also, this code contains provisions for a change in OpenDoc's 
  1728.         behavior as of 1.2.  Prior to 1.2, OpenDoc does not touch the subject
  1729.         attribute while after 1.2 OpenDoc replaces the subject attribute with
  1730.         the token it got when resolving the subject, just like it does with the
  1731.         direct parameter.  This code copes with that scenario.
  1732.         
  1733.         Finally, this code exposes the details about the standard part token,
  1734.         which is not made public in the OpenDoc interfaces.  Nevertheless, it
  1735.         is necessary and accepted that people will be looking at standard part
  1736.         tokens, so this is an acceptable way of dealing with life.
  1737.     */
  1738.     
  1739.     TRY
  1740.         ODDescToAEDesc(message, &realEvent);
  1741.         
  1742.         // create an ODOSLToken (which is essentially an ODDesc)
  1743.         oslToken = new ODOSLToken;
  1744.         THROW_IF_NULL(oslToken);
  1745.         oslToken->InitODOSLToken(ev);
  1746.         
  1747.         // look for and/or at the direct parameter
  1748.         error = AEGetKeyDesc(&realEvent, keyDirectObject, typeWildCard, &obj);
  1749.         THROW_IF_ERROR( AEDescToODDesc(&obj, oslToken ) );
  1750.         
  1751.         // if it is missing or not a token then check the subject attribute
  1752.         if (error != noErr || !resolver->IsODToken(ev, oslToken)) {
  1753.             // there is no direct parameter or it is not an ODToken (i.e. we couldn't resolve it)
  1754.             THROW_IF_ERROR( AEGetAttributeDesc(&realEvent, keySubjectAttr, typeWildCard, &obj) );
  1755.             if (obj.descriptorType != typeObjectSpecifier) {
  1756.                 // obj is a token or null
  1757.                 AEDescToODDesc(&obj, oslToken);
  1758.                 WASSERT(resolver->IsODToken(ev, oslToken) || 
  1759.                         oslToken->GetDescType(ev) == typeNull);
  1760.             }
  1761.             else {
  1762.                 // the subject was an object so we need to resolve it
  1763.                 
  1764.                 // create a wrapper ODObjectSpec (which is just an ODDesc)
  1765.                 ODObjectSpec* objWrapper = new ODObjectSpec();
  1766.                 THROW_IF_NULL(objWrapper);
  1767.                 objWrapper->InitODObjectSpec(ev);
  1768.  
  1769.                 // copy the obj into the ODObjectSpec & dispose of the original
  1770.                 THROW_IF_ERROR( AEDescToODDesc(&obj, objWrapper ) );
  1771.                 THROW_IF_ERROR( AEDisposeDesc(&obj) );
  1772.  
  1773.                 // prepare the output ODOSLToken
  1774.                 oslToken->SetDescType(ev, typeNull);
  1775.                 
  1776.                 // resolve the subject attribute & copy the token to obj
  1777.                 resolver->Resolve(ev, objWrapper, oslToken, kODAppShell);
  1778.                 THROW_IF_ERROR( ODDescToAEDesc(oslToken, &obj) );
  1779.     
  1780.                 ODDeleteObject(objWrapper);
  1781.                 disposeToken = kODTrue;
  1782.             }
  1783.         }
  1784.         // At this point both obj & oslToken contain the same data, 
  1785.         // the token obtained from resolving either the direct parameter
  1786.         // or the subject attribute.
  1787.         WASSERT(obj.descriptorType == oslToken->GetDescType(ev));    // a cheap check
  1788.         
  1789.         if (obj.descriptorType != typeNull && obj.dataHandle != kODNULL) {
  1790.             // there is an object, so we need to figure out if it is a 
  1791.             // standard part token and get the part and frame from it or
  1792.             // if not, get the context of the token, which should be our part.
  1793.             ASSERT(resolver->IsODToken(ev, oslToken), 23);
  1794.             userToken = resolver->GetUserToken(ev, oslToken);
  1795.             ODDescToAEDesc(userToken, &obj);
  1796.             // CanBeStandardPartToken allows developers to make their own tokens
  1797.             // which can be coerced into standard part tokens.
  1798.             if (CanBeStandardPartToken(&obj)) {
  1799.                 // A standard part token is merely a part and frame reference, but
  1800.                 // this routine allows us to hide that info from this code.
  1801.                 PartFrameFromStandardPartToken(&obj, &contextPart, &contextFrame);
  1802.             }
  1803.             else {
  1804.                 // This context was saved during the object resolution and should
  1805.                 // be the part and frame which contains the object referenced.
  1806.                 resolver->GetContextFromToken( ev, oslToken, &contextPart, &contextFrame);
  1807.             }
  1808.             // If we have a frame, then try getting the real part from the part wrapper.
  1809.             if (contextFrame) {
  1810.                 TRY
  1811.                     realPart = contextPart->GetRealPart(ev);
  1812.                     samePart = ODObjectsAreEqual(ev, realPart, part);
  1813.                     contextPart->ReleaseRealPart(ev);
  1814.                 CATCH_ALL
  1815.                     WARN("Couldn't get real part, error == %d", ErrorCode());
  1816.                 ENDTRY
  1817.             }
  1818.         }
  1819.         else {
  1820.             // Since we have a null reference, we must be the root frame
  1821.             // because without a reference, we can't target anyone else, so
  1822.             // we'll grab the front window and get the root frame that way. 
  1823.             contextFrame = GetDefaultRootFrame(ev, session);
  1824.             samePart = kODTrue;
  1825.         }
  1826.         
  1827. //        WARN("Meow - part = %x, wrapper = %x, frame = %x, Parts %s", 
  1828. //                part, contextPart, contextFrame, samePart ? "match" : "don't match");
  1829.  
  1830.         // complain if this code and the utility code don't agree
  1831.         utilSaysHandle = ShouldHandleEvent(part, message, reply, (ODSession*)handlerRefcon);
  1832.         if (utilSaysHandle != samePart) {
  1833.             WARN("Meow - I say %shandle it, SEUtils says %shandle it.", 
  1834.                     samePart ? "" : "don't ", 
  1835.                     utilSaysHandle ? "" : "don't ");
  1836.         }
  1837.  
  1838.         // At this point, if samePart is true, then we're supposed to handle this event.
  1839.         // If samePart is not true then we should return errAEEventNotHandled and let
  1840.         // the event get redispatched to the correct part.  If we are the root part, then
  1841.         // contextPart will be null simply because I don't think we need it given the 
  1842.         // part reference that was passed in.  Additionally, if you are planning on 
  1843.         // keeping any of these SOM objects for any length of time you should Acquire them.
  1844.         if (samePart) {
  1845.             error = noErr;
  1846.         }
  1847.         else
  1848.             error = errAEEventNotHandled;
  1849.     CATCH_ALL
  1850.         error = ErrorCode();
  1851.     ENDTRY
  1852.     
  1853.     AEDisposeDesc(&realEvent);
  1854.     AEDisposeDesc(&realEvent);
  1855.     AEDisposeDesc(&obj);
  1856.     if (disposeToken)
  1857.         resolver->DisposeToken(ev, oslToken);
  1858.     else
  1859.         ODDeleteObject(oslToken);    
  1860.     return error;
  1861. }    // HandleMeow
  1862.  
  1863.  
  1864.